Writing Our First Code
Now
we need to modify the service so that it does something useful.
Initially this will not be a major change, but later on we will be
expanding the service.
In Visual Studio, click the Tutorials.vb tab and you will again see the <OnStart> and <OnStop> code. We will modify both methods to write an entry into the Application log.
This
simple application demonstrates the process of creating a service in
Visual Basic 2008; modifying the design template provided by Visual
Studio 2008; and creating, building, and then installing the service.
Click the <OnStart> method. Under the comments section, we’ll first add an error handler:
Try
Catch ex As Exception
End Try
You
should never leave your code unprotected from exceptions, especially in
a service where the message box that appears when an unhandled
exception occurs cannot be processed without special implementation.
You
use a Try/Catch block to capture exceptions that are thrown by your
code if it generates custom exceptions, or to catch exceptions thrown
by internal .NET classes. The important thing to notice here is that we
are capturing an exception called Exception. In Visual Basic terms,
this means any exception—or in other words, a catchall. Although using
a catchall here is fine, you should always code your applications to
catch only the specific exceptions that you can expect and then do what
you need to based on that specific exception. We will deal more with
this as we progress.
Modifying the <OnStart> Method
In the <OnStart>
method we are going to write an event to the Application log when the
service is told to start the “Hello, World” of beginner services. We
plan to implement other code in this method in the future, so this will
help you understand how to standardize code in your services.
Note
A service should not perform a large amount of work in the <OnStart>
method. It must return within 30 seconds or the Service Control Manager
will time out. In this example, the work is minimal, but in the future,
as the service extends, we will avoid adding too much overhead to this
method. |
In Listing 1 we will modify the <OnStart>
method to log an event as the user starts the service. If there is an
error, we will do nothing for now. If the attempt to write the startup
message fails, most likely an attempt to write a failure message to the
Application log would also fail.
Listing 1. Modifications to <OnStart> to write to the Application log.
Try Dim StartLog As EventLog = New EventLog ("Application") StartLog.Source = "Tutorials" StartLog.WriteEntry("Tutorials Starting", EventLogEntryType.Information, 1000) StartLog.Dispose() Catch ex As Exception 'We Catch the Exception 'to avoid any unhandled errors 'and we will stop the service if any occur here Me.Stop() End Try
|
The preceding code creates an instance of the EventLog
class, sets the source to Tutorials, writes an Entry, and then disposes
of the EventLog instance. When this happens, the method returns and the
Service Control Manager assumes the service is running.
You
will note that in Catch we aren’t actually doing anything. For now this
is okay. However, in the future—and for real services—you may well want
to shut down the service if this method fails, thereby limiting the
work load of the <OnStart>.
Modifying the <OnStop> Method
In the <OnStop> method, shown in Listing 2,
we are going to modify the method to write a single event to the
Application log when the user stops the service. As with the <OnStart> method, we won’t try to log a failure of the service to write the stop message.
Listing 2. Modifications to <OnStop> to write to the Application log.
Try Dim StopLog As EventLog = New EventLog ("Application") StopLog.Source = "Tutorials" StopLog.WriteEntry("Tutorials Stopping", EventLogEntryType.Information, 1001) StopLog.Dispose() Catch ex As Exception
'We Catch the Exception 'to avoid any unhandled errors 'since we are stopping and 'logging an event is what failed 'we will merely write the output 'to the debug window Debug.WriteLine("Error stopping service: " + ex.ToString()) End Try
|
You will notice that the only real difference here between <OnStart> and <OnStop>
is that we are sending a different message with a different EventID so
that we can easily distinguish what the service is doing and validate
that the code is working properly.
Modifying the <OnPause> Method
Once again in the <OnPause> method (shown in Listing 1-3)
we are going to modify the method to write a single event to the
Application log when the user pauses the service. As with <OnStart> we won’t try to log a failure of the service to write the pause message.
Listing 3. Modifications to <OnPause> to write to the Application log.
Try Dim PauseLog As EventLog = New EventLog ("Application") PauseLog.Source = "Tutorials" PauseLog.WriteEntry("Tutorials Pausing", EventLogEntryType.Information, 1002) StopLog.Dispose() Catch ex As Exception
'We Catch the Exception 'to avoid any unhandled errors 'since we are pausing and 'logging an event is what failed 'we will merely write the output 'to the debug window Debug.WriteLine("Error pausing service: " + ex.ToString()) Me.Stop() End Try
|
Modifying the <OnContinue> Method
Finally, in the <OnContinue> method (shown in Listing 1-4)
we are going to modify the method to write a single event to the
Application log when the user continues the service after it has been
paused. As with <OnStart> we won’t try to log a failure of the service to write the continue message.
Listing 4. Modifications to <OnContinue> to write to the Application log.
Try
Dim ContinueLog As EventLog = New EventLog ("Application")
ContinueLog.Source = "Tutorials"
ContinueLog.WriteEntry("Tutorials Continuing", EventLogEntryType.Information, 1003)
StopLog.Dispose()
Catch ex As Exception
'We Catch the Exception
'to avoid any unhandled errors
'since we are resuming and
'logging an event is what failed
'we will merely write the output
'to the debug window
Debug.WriteLine("Error resuming service: " + ex.ToString())
Me.Stop()
End Try